#ifndef __SIM_H__
#define __SIM_H__

#include "sim_util.h" //Must be included before types.h to avoid boost namespace pollution in RandomLib stuff.
#include "types.h"

#include <vector>
#include <algorithm>
#include <list>

//toposort is a vector of vertex_descriptors that contains a topological ordering of the
//vertices of g in reverse order.  That is, by using a reverse_iterator through toposort,
//vertices should be visited in an order such that their predecessor vertices, if any,
//have already been visited.

//TODO: Add critical path, maybe occupancy
struct sim_result
{
  double time;
  double totalwork;
  std::list<Vertex> criticalpath;
};

class sim {
  public:
    static sim_result simulate(graph_t &g, const std::vector<Vertex> &toposort, const std::vector<Vertex> &inputs, const std::vector<Vertex> &outputs, const int nprocs, const bool dump = false, const bool fixedSigma = false, const float sigmaVal = 0.0f, const float commPenalty = 1.0, const sim_mapping_strategy mapStrategy = s_greedy);
    static void calc_depths(graph_t &g, const std::vector<Vertex> &toposort);
    static void calc_depths_recursive(graph_t &g, const std::vector<Vertex> &toposort, const Vertex root, const int depthv, const float deptht);
    static int get_proc_hmetis(graph_t &g, Vertex v, std::vector<float> &nextReady, const int nprocs);
    static int get_proc_earliest_ready(graph_t &g, Vertex v, std::vector<float> &nextReady, const int nprocs);
    static std::list<Vertex> find_critical_path(graph_t &g);
};

#endif //#ifndef __SIM_H__
